package com.tth.learn.addproperties.java;

/**
 * 生产者/消费者问题
 * <p>
 * 生产者生产产品给店员，消费者从店员处取走产品。
 * 店员一次只能维护固定数量的产品（如20）。
 * 当生产者试图生产更多的产品，店员会叫生产者停一下。
 * 当店中没有产品的时候，店员会通知消费者等一下，待有产品的时候再用纸消费者
 *
 * @Author tth
 * @Date 2022/11/2 10:04
 */
public class ProductorAndConsumerTest {
    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        Productor productor = new Productor(clerk);
        Consumer consumer = new Consumer(clerk);

        Thread pThread = new Thread(productor);
        pThread.setName("生产者");
        Thread cThread = new Thread(consumer);
        cThread.setName("消费者");

        pThread.start();
        cThread.start();


    }
}

/**
 * 店员
 */
class Clerk {
    // 产品数量
    private int num = 0;

    public Clerk() {
    }

    // 生产产品
    public synchronized void product() {
        if (num >= 20) {
            try {
                System.out.println(Thread.currentThread().getName() + "您好，产品数量过多，请等待...");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            // 假设生产产品需要1秒钟
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            num++;
            System.out.println(Thread.currentThread().getName() + "生产了一个产品，目前产品数量为：" + num);

            // 唤醒生产者线程
            notify();
        }
    }

    // 消费产品
    public synchronized void consume() {
        if (num <= 0) {
            try {
                System.out.println(Thread.currentThread().getName() + "您好，产品数量不足，请等待...");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            // 假设消费产品需要0.1秒钟
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            num--;
            System.out.println(Thread.currentThread().getName() + "消费了一个产品，目前产品数量为：" + num);

            // 1秒后唤醒生产者线程
            notify();
        }
    }
}

/**
 * 生产者
 */
class Productor implements Runnable {
    private Clerk clerk;

    public Productor(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        while (true) {
            clerk.product();
        }
    }


}

/**
 * 消费者
 */
class Consumer implements Runnable {
    private Clerk clerk;

    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }

    @Override
    public void run() {
        while (true) {
            clerk.consume();
        }
    }

}